package com.dupf.common.util;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.net.URLDecoder;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class Tools {
    private static String SERVER_IP = "";

    /**
     * codeZeroNineSequence A-Z0-9
     */
    private static char[] AZ09Sequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
            'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };

    /**
     * codeZeroNineSequence 0-9
     */
    private static char[] codeZeroNineSequence = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
    /**
     * codeOneNineSequence 1-9
     */
    private static char[] codeOneNineSequence = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };

    private static double rad(double d) {
        return d * Math.PI / 180.0;
    }

    public static Timestamp getCurrentTime() {
        return null;
    }

    public static int getYear(String date) {
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        int birthDayYear = 0;
        if (date != null && date.length() > 4) {
            birthDayYear = Integer.parseInt(date.substring(0, 4));
        }

        return year - birthDayYear;
    }

    public static String formatDate(String date) {
        SimpleDateFormat dateformat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String newDate = dateformat1.format(date);

        return newDate;
    }

    // length is RAND code length
    public static String getRandWithCode(String code, int length) {

        Random random = new Random();

        StringBuffer randomCode = new StringBuffer();

        for (int i = 0; i < length; i++) {

            String strRand = (code.startsWith("AZ09")) ? String.valueOf(AZ09Sequence[random.nextInt(36)])
                    : String.valueOf(codeZeroNineSequence[random.nextInt(10)]);

            randomCode.append(strRand);
        }
        return randomCode.toString();
    }

    public static String getZeroNineRand(int length) {

        Random random = new Random();

        StringBuffer randomCode = new StringBuffer();
        if (length > 0) {
            randomCode.append(String.valueOf(codeOneNineSequence[random.nextInt(9)]));
        }

        for (int i = 1; i < length; i++) {
            String strRand = String.valueOf(codeZeroNineSequence[random.nextInt(10)]);
            randomCode.append(strRand);
        }

        return randomCode.toString();
    }

    public static String getOneNineRand(int length) {
        Random random = new Random();
        StringBuffer randomCode = new StringBuffer();

        for (int i = 0; i < length; i++) {
            String strRand = String.valueOf(codeOneNineSequence[random.nextInt(9)]);
            randomCode.append(strRand);
        }

        return randomCode.toString();
    }

    public static String string2Unicode(String s) {
        try {
            StringBuffer out = new StringBuffer("");
            byte[] bytes = s.getBytes("unicode");
            for (int i = 2; i < bytes.length - 1; i += 2) {
                out.append("u");
                String str = Integer.toHexString(bytes[i + 1] & 0xff);

                for (int j = str.length(); j < 2; j++) {
                    out.append("0");
                }

                String str1 = Integer.toHexString(bytes[i] & 0xff);

                out.append(str);
                out.append(str1);
                out.append(" ");
            }

            return out.toString().toUpperCase();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return null;
    }

    public static int getRandom(int maxmum) {
        Random r = new Random();
        return r.nextInt(maxmum);
    }

    /**
     * 借鉴sigmoid函数，将实数范围映射到[0,1]的区间
     * 
     * @param uid
     *            用户标识
     * @param base
     *            基数10,50,100,500,1000,5000,10000
     * @param factors
     *            其它影响因子
     * @return
     */
    public static int getEvaluation(int uid, int base, int... factors) {
        double eval = 1;
        for (int factor : factors) {
            double exp = Math.pow(Math.E, -Math.log(factor + 1));
            eval *= (1 - exp) / (1 + exp);
        }

        Random r = new Random(uid);
        double personal = r.nextDouble();

        return (int) (personal * eval * base);
    }

    public static String getServerIp() {

        synchronized (SERVER_IP) {
            try {
                if (StringUtils.isEmpty(SERVER_IP)) {
                    Document doc = Jsoup.connect("http://1212.ip138.com/ic.asp").get();
                    String center = doc.select("center").text();
                    int start = center.indexOf("[");
                    int end = center.lastIndexOf("]");

                    if ((start >= 1) && (end >= 1)) {
                        SERVER_IP = center.substring(start + 1, end);
                    }
                }
            } catch (Exception e) {

            }

            return SERVER_IP;
        }
    }

    /**
     *
     * @param content
     * @param width
     *            图像宽度
     * @param height
     *            图像高度
     * @param format
     *            图像类型
     * @return
     */
    public static String getQrCode(String content, int width, int height, String format) {
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");

        // 生成矩阵
        try {
            BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);

            int[] rec = bitMatrix.getEnclosingRectangle();
            int resWidth = rec[2] + 1;
            int resHeight = rec[3] + 1;
            BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);
            resMatrix.clear();
            for (int i = 0; i < resWidth; i++) {
                for (int j = 0; j < resHeight; j++) {
                    if (bitMatrix.get(i + rec[0], j + rec[1])) {
                        resMatrix.set(i, j);
                    }
                }
            }

            width = resMatrix.getWidth();
            height = resMatrix.getHeight();
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    int color = Color.WHITE.getRGB();
                    if (resMatrix.get(x, y)) {
                        color = Color.BLACK.getRGB();
                    }

                    image.setRGB(x, y, color);
                }
            }

            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            ImageIO.write(image, format, outputStream);
            return Base64.encodeBase64String(outputStream.toByteArray());
        } catch (Exception e) {

        }

        return null;
    }

    @SuppressWarnings("deprecation")
    public static String getClassFilePath() {
        String path = URLDecoder.decode(Tools.class.getResource("").getPath());
        path = path.substring(0, path.indexOf("classes") + 8);
        return path;
    }

    public static String getClassFilePathNew() throws UnsupportedEncodingException {
        String path = URLDecoder.decode(Tools.class.getResource("").getPath(), "utf-8");
        path = path.substring(1, path.indexOf("classes") + 8);
        return path;
    }

    public static void generateCopySourceToTarget() {

        Class classCCCCCCC = null;
        try {
            classCCCCCCC = Class.forName("com.dupf.product.dao.model.ProductDetail");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        Field[] allFields = classCCCCCCC.getDeclaredFields();
        String target = "target" + classCCCCCCC.getSimpleName();
        String source = "source" + classCCCCCCC.getSimpleName();

        System.out.println(classCCCCCCC.getSimpleName() + " " + "target" + classCCCCCCC.getSimpleName() + " = new "
                + classCCCCCCC.getSimpleName() + "();");
        for (Field field : allFields) {
            if (field.getName().equals("serialVersionUID") || field.getName().equals("id")) {
                continue;
            }

            System.out.println(target + ".set" + fristToUpper(field.getName()) + "(" + source + ".get"
                    + fristToUpper(field.getName()) + "());");

        }
    }

    public static String fristToUpper(String name) {
        name = name.substring(0, 1).toUpperCase() + name.substring(1);
        return name;

    }

    public static String fristToLower(String name) {
        name = name.substring(0, 1).toLowerCase() + name.substring(1);
        return name;

    }

    public static void main(String args[]) {//215*212 297*278
        //System.out.println(getQrCode("http://www.jalidata.com", 297, 278, "png"));
//        String randomCode = Tools.getRandWithCode("AZ09", 8);

        generateCopySourceToTarget();
    }
}
